﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SCIE_DTL;
using System.Data;

namespace SCIE_DAL
{
    /// <summary>
    /// Autor: Guilherme Elias <deixapramim@gmail.com>
    ///                  Michael Stumpf <>
    /// Data: 08/05/2009 
    /// Descricao: Class base para qualquer equipamento do sistema
    /// </summary>
    /// <typeparam name="Equipamento"></typeparam>
    public abstract class EquipamentoDAO<Equipamento> 
        where Equipamento:class, SCIE_DTL.ITransferenciaDados, new()
    {
        #region Atributos

        protected DataFactory factory = new DataFactory();

        #endregion

        #region Métodos

        /// <summary>
        /// Metodo responsavel por iniciar a insercao de um novo equipamento
        /// </summary>
        /// <param name="dto"></param>
        public virtual void AdicionarEquipamento(ITransferenciaDados dto)
        {
            IDbCommand comando = CriarComandoInsercao(dto);
            try
            {
                comando.Connection.Open();
                comando.ExecuteNonQuery();
            }
            finally
            {
                comando.Dispose();
            }
        }

        /// <summary>
        /// Metodo que resgata todos os determinados tipos de equipamentos
        /// </summary>
        /// <returns></returns>
        public List<Equipamento> BuscarTodos()
        {
            IDbCommand comando = CriarComandoBuscarTodos();
            try
            {
                comando.Connection.Open();
                IDataReader leitor = comando.ExecuteReader();
                List<Equipamento> resultado = new List<Equipamento>();
                while (leitor.Read())
                {
                    Equipamento item = new Equipamento();
                    PopularDto(leitor, item);
                    resultado.Add(item);
                }

                return resultado;
            }
            finally
            {
                comando.Dispose();
            }
        }
        
        /// <summary>
        /// Comando que cria um objeto do tipo IDBCommand para executar
        /// query no banco resgatando todos os tipos de equipamentos
        /// determinados
        /// </summary>
        /// <returns></returns>
        internal virtual IDbCommand CriarComandoBuscarTodos()
        {
            return factory.CreateCommand("SELECT * FROM " + ObterNomeTabela() + "");
        }

        /// <summary>
        /// Metodo responsavel por atualiza um equipamento atraves da
        /// etiqueta do mesmo
        /// </summary>
        /// <param name="etiqueta"></param>
        /// <param name="newDto"></param>
        public virtual void AtualizarEquipamento(string etiqueta, Equipamento newDto)
        {
            IDbCommand command = CriarComandoAtualizacao(etiqueta, newDto);
            try
            {
                command.Connection.Open();
                command.ExecuteNonQuery();
            }
            finally
            {
                command.Dispose();
            }
        }

        /// <summary>
        /// Metodo que realiza a remocao de um equipamento atraves de usa etiqueta
        /// </summary>
        /// <param name="etiqueta"></param>
        public virtual void RemoverEquipamento(string etiqueta)
        {
            IDbCommand command = CriarComandoRemocao(etiqueta);
            try
            {
                command.Connection.Open();
                command.ExecuteNonQuery();
            }
            finally
            {
                command.Dispose();
            }
        }

        /// <summary>
        /// Metodo que realiza a remocao de um equipamento atraves do objeto equipamento
        /// </summary>
        /// <param name="dto"></param>
        public virtual void RemoverEquipamento(Equipamento dto)
        { 
            IDbCommand command = CriarComandoRemocao(dto);
            try
            {
                command.Connection.Open();
                command.ExecuteNonQuery();
            }
            finally
            {
                command.Dispose();
            }
        }

        /// <summary>
        /// Metodo que realiza busca de um determinado equipamento pela sua etiqueta.
        /// </summary>
        /// <param name="etiqueta"></param>
        /// <returns></returns>
        public Equipamento BuscarEquipamentoPorEtiqueta(string etiqueta)
        {
            IDbCommand comando = CriarComandoBuscaEquipamentoPorEtiqueta(etiqueta);
            try
            {
                comando.Connection.Open();
                IDataReader leitor = comando.ExecuteReader();
                if (leitor.Read())
                {
                    Equipamento item = new Equipamento();
                    PopularDto(leitor, item);
                    return item;
                }
                else
                    return null;
            }
            finally
            {
                comando.Dispose();
            }
        }

        /// <summary>
        /// Metodo responsavel por gerar o codigo identificador da etiqueta
        /// </summary>
        /// <returns></returns>
        public virtual int ObterUltimaEtiqueta()
        {
            return factory.ObterUltimaEtiqueta();
        }
        
        #endregion 
        
        # region  Métodos abstratos

        /// <summary>
        /// Metodo abstrato que cria a instrução sql a ser executada
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        internal abstract IDbCommand CriarComandoInsercao(ITransferenciaDados dto);

        /// <summary>
        /// Metodo abstrato que representara o nome da tabela a qual devera 
        /// ser criada a instrucao SQL
        /// </summary>
        /// <returns></returns>
        internal abstract string ObterNomeTabela();

        /// <summary>
        /// Metodo abstrato que sera responsavel por popular
        /// junto ao objeto item todos os atributos resgatados do banco
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="item"></param>
        internal abstract void PopularDto(IDataReader leitor, Equipamento equipamento);

        /// <summary>
        /// Metodo abstrato que sera responsavel por criar a instrucao SQL
        /// para atualizar determinado equipamento
        /// </summary>
        /// <returns></returns>
        internal abstract IDbCommand CriarComandoAtualizacao(string etiqueta, Equipamento newDto);

        /// <summary>
        /// Metodo abstrato responsavel por criar o comando 
        /// de remocao de um determinado equipamento baseado
        /// no numero de sua etiqueta
        /// </summary>
        /// <param name="etiqueta"></param>
        /// <returns></returns>
        internal abstract IDbCommand CriarComandoRemocao(string etiqueta);

        /// <summary>
        /// Metodo abstrato responsavel por criar o comando 
        /// de remocao de um determinado equipamento baseado
        /// no objeto equipamento passado por parametro
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        internal abstract IDbCommand CriarComandoRemocao(Equipamento dto);

        /// <summary>
        /// Metodo abstrato que realiza a busca de um determinado
        /// equipamento atraves de sua etiqueta
        /// </summary>
        /// <param name="etiqueta"></param>
        /// <returns></returns>
        internal abstract IDbCommand CriarComandoBuscaEquipamentoPorEtiqueta(string etiqueta);


        #endregion

    }
}
